mod domain_trans;
mod sql_trans;
mod struct_trans;
mod values_trans;

use model_graph_types::{
    database::DataSource,
    transform::{
        DataTransformOptions, DataTransformUnit, DomainTransformerOptions, DomainTransformerUnit,
    },
};

/// 根据数据库获取到元数据
pub async fn transform(
    source: &DataSource,
    target: &DataSource,
    units: Vec<DataTransformUnit>,
    options: DataTransformOptions,
) -> anyhow::Result<()> {
    for unit in units {
        let result = match unit {
            DataTransformUnit::Values(values_unit) => {
                values_trans::transform(source, target, &values_unit, &options).await
            }
            DataTransformUnit::Struct(struct_unit) => {
                struct_trans::transform(source, target, &struct_unit, &options).await
            }
            DataTransformUnit::Sql(sql_unit) => {
                sql_trans::transform(source, target, &sql_unit, &options).await
            }
        };
        if !options.ignore_errs {
            if let Err(err) = result {
                tracing::error!("transform:{}", err);
                return Err(err);
            }
        }
    }
    Ok(())
}

/// 域数据转移
pub async fn domain_transform(
    source: &DataSource,
    target: &DataSource,
    units: Vec<DomainTransformerUnit>,
    options: DomainTransformerOptions,
) -> anyhow::Result<()> {
    for unit in &units {
        let result = domain_trans::domain_transform(source, target, unit, &options).await;
        if !options.ignore_errs {
            if let Err(err) = result {
                tracing::error!("transform:{}", err);
                return Err(err);
            }
        }
    }
    Ok(())
}

/// 领域数据转移
pub async fn export_domain_to_file(
    source: &DataSource,
    target: &String,
    units: Vec<DomainTransformerUnit>,
    options: DomainTransformerOptions,
) -> anyhow::Result<()> {
    for unit in &units {
        let result = domain_trans::export_domain_to_file(source, target, unit, &options).await;
        if !options.ignore_errs {
            if let Err(err) = result {
                tracing::error!("transform:{}", err);
                return Err(err);
            }
        }
    }
    Ok(())
}

/// 领域数据转移
pub async fn import_domain_from_file(
    source: &String,
    target: &DataSource,
    units: Vec<DomainTransformerUnit>,
    options: DomainTransformerOptions,
) -> anyhow::Result<()> {
    for unit in &units {
        let result = domain_trans::import_domain_from_file(source, target, unit, &options).await;
        if !options.ignore_errs {
            if let Err(err) = result {
                tracing::error!("transform:{}", err);
                return Err(err);
            }
        }
    }
    Ok(())
}

/// 清空领域
pub async fn clear_domain(
    meta_datasource: &DataSource,
    domains: Vec<String>,
) -> anyhow::Result<()> {
    domain_trans::clear_domain(meta_datasource, domains).await
}

/// 删除领域
pub async fn delete_domain(
    meta_datasource: &DataSource,
    domains: Vec<String>,
) -> anyhow::Result<()> {
    domain_trans::delete_domain(meta_datasource, domains).await
}
